﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using ClientDependency.Core;
using ClientDependency.Core.Controls;
using Our.Umbraco.DataType.Bitly.Properties;
using umbraco;
using umbraco.cms.businesslogic;
using umbraco.cms.businesslogic.web;
using umbraco.interfaces;

// embed resources
[assembly: WebResource("Our.Umbraco.DataType.Bitly.Bitly.css", "text/css")]

namespace Our.Umbraco.DataType.Bitly
{
	/// <summary>
	/// The bit.ly URL shortener control.
	/// </summary>
	public class BitlyControl : PlaceHolder
	{
		private const string HTTP = "http://";

		/// <summary>
		/// Initializes a new instance of the <see cref="BitlyControl"/> class.
		/// </summary>
		public BitlyControl()
		{
		}

		/// <summary>
		/// Gets or sets the options.
		/// </summary>
		/// <value>The options.</value>
		public BitlyOptions Options { get; set; }

		/// <summary>
		/// Gets or sets the long URL.
		/// </summary>
		/// <value>The long URL.</value>
		public string LongUrl { get; set; }

		/// <summary>
		/// Gets or sets the short URL.
		/// </summary>
		/// <value>The short URL.</value>
		public string ShortUrl { get; set; }

		/// <summary>
		/// Gets or sets the message.
		/// </summary>
		/// <value>The message.</value>
		protected Label Message { get; set; }

		/// <summary>
		/// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
		/// </summary>
		/// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			this.EnsureChildControls();
		}

		/// <summary>
		/// Raises the <see cref="E:System.Web.UI.Control.Load"/> event.
		/// </summary>
		/// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			// Adds the client dependencies.
			ScriptManager.RegisterClientScriptInclude(this.Page, this.GetType(), "bit.ly api", String.Format("http://bit.ly/javascript-api.js?version=latest&login={0}&apiKey={1}", this.Options.BitlyUsername, this.Options.BitlyApiKey));
			ClientDependencyLoader.Instance.RegisterDependency("Our.Umbraco.DataType.Bitly.Bitly.css", ClientDependencyType.Css);
		}

		/// <summary>
		/// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
		/// </summary>
		protected override void CreateChildControls()
		{
			base.CreateChildControls();

			// create the controls
			this.Message = new Label() { Visible = false };

			// add the controls
			this.Controls.Add(this.Message);

			if (string.IsNullOrEmpty(this.Options.BitlyUsername) || string.IsNullOrEmpty(this.Options.BitlyUsername))
			{
				this.Message.Text = Resources.Message_NoApiKey;
				this.Message.Visible = true;
			}

			int nodeId = 0;
			if (int.TryParse(HttpContext.Current.Request.Params.Get("id"), out nodeId))
			{
				// get the current document
				Document doc = new Document(nodeId);

				if (!doc.Published)
				{
					this.Message.Text = Resources.Message_NotPublished;
					this.Message.Visible = true;
				}
				else
				{
					String niceUrl = umbraco.library.NiceUrl(nodeId);

					// if the niceUrl doesn't start with 'http', then assume there is no domain/hostname
					if (!niceUrl.StartsWith(HTTP))
					{
						niceUrl = String.Concat(HTTP, HttpContext.Current.Request.ServerVariables["SERVER_NAME"], niceUrl);
					}

					this.LongUrl = niceUrl; // Helper.GuessNiceUrl(nodeId)

					// if the data is empty, or doesn't start with 'http', then display the 'generate' button
					if (String.IsNullOrEmpty(this.ShortUrl) || !this.ShortUrl.StartsWith(HTTP))
					{
						Button btnShortener = new Button();
						btnShortener.Text = Resources.Message_GenerateShortUrlURL;
						btnShortener.Click += new EventHandler(this.btnShortener_Click);

						this.Controls.Add(btnShortener);
					}
					else
					{
						HyperLink linkShortUrl = new HyperLink()
						{
							Text = this.ShortUrl,
							NavigateUrl = this.ShortUrl,
							Target = "_blank"
						};
						this.Controls.Add(linkShortUrl);

						// clear / remove button
						Button btnClear = new Button() { Text = "Clear" };
						btnClear.Click += new EventHandler(this.btnClear_Click);
						btnClear.Style.Add("margin-left", "10px");
						this.Controls.Add(btnClear);

						this.Controls.Add(new LiteralControl("<div id=\"bitly-info-toggle\"><img src=\"images/expand.png\" /><span>View stats and other info for this link.</span></div>"));
						this.Controls.Add(new LiteralControl("<div id=\"bitly-info-results\"></div>"));

						// include info
						// include stats
						// maybe validate link - comparing the "long url" from the info data?
					}
				}
			}
			else
			{
				this.Message.Text = Resources.Message_NoNodeId;
				this.Message.Visible = true;
			}
		}

		/// <summary>
		/// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
		/// </summary>
		/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
		protected override void Render(HtmlTextWriter writer)
		{
			base.Render(writer);

			if (this.Message.Visible)
			{
				//this.Message.RenderControl(writer);
			}
			else
			{
				//foreach (Control control in this.Controls)
				//{
				//    control.RenderControl(writer);
				//}

				// add javascript
				var javascriptMethods = string.Concat(@"
function modulesReady() {
	var url = '", this.ShortUrl, @"';
	BitlyClient.appendStatsTable({'shortUrl': url}, 'bitly-info-results');
}
BitlyClient.addPageLoadEvent(function(){
	BitlyClient.loadModules(['stats'], 'modulesReady');
});
jQuery(window).load(function(){
	$('#bitly-info-toggle').toggle(
		function(){
			$('span', this).text('Hide stats and other info for this link.');
			$('img', this).attr('src', 'images/collapse.png');
			$('#bitly-info-results').slideDown('fast');
		},
		function(){
			$('span', this).text('View stats and other info for this link.');
			$('img', this).attr('src', 'images/expand.png');
			$('#bitly-info-results').slideUp('fast');
		}
	);
});
");
				var javascript = string.Concat("<script type='text/javascript'>", javascriptMethods, "</script>");
				writer.WriteLine(javascript);
			}
		}

		/// <summary>
		/// Handles the Click event of the btnShortener control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		protected void btnShortener_Click(object sender, EventArgs e)
		{
			// clear the controls from the template container
			this.Controls.Clear();

			// call Bit.ly to generate a short URL
			this.ShortUrl = Helper.GetBitlyUrl(this.Options.BitlyUsername, this.Options.BitlyApiKey, this.LongUrl);

			if (String.IsNullOrEmpty(this.ShortUrl))
			{
				// get hold of the actual error message
				this.Controls.Add(new LiteralControl(Resources.Message_ErrorBitly));
			}
			else
			{
				// show the link
				HyperLink linkShortUrl = new HyperLink()
				{
					Text = this.ShortUrl,
					NavigateUrl = this.ShortUrl,
					Target = "_blank"
				};
				this.Controls.Add(linkShortUrl);

				this.Controls.Add(new LiteralControl("  <em>Remember to Save &amp; Publish this content page.</em>"));
			}
		}

		/// <summary>
		/// Handles the Click event of the btnClear control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		protected void btnClear_Click(object sender, EventArgs e)
		{
			// clear the controls from the template container
			this.Controls.Clear();

			// save the property value
			this.ShortUrl = string.Empty;

			this.Controls.Add(new LiteralControl("<em>The Bit.ly Url has been cleared from this page.</em>"));
		}
	}
}
